package com.zndroid.utils;

import android.app.Activity;
import android.content.Context;

import androidx.annotation.NonNull;
import androidx.collection.ArrayMap;

import com.zndroid.utils.impl.AppUtil;
import com.zndroid.utils.impl.AssetsUtil;
import com.zndroid.utils.impl.CleanerUtil;
import com.zndroid.utils.impl.ClipboardUtil;
import com.zndroid.utils.impl.CollectUtil;
import com.zndroid.utils.impl.CryptoUtil;
import com.zndroid.utils.impl.DeviceUtil;
import com.zndroid.utils.impl.FileUtil;
import com.zndroid.utils.impl.NetUtil;
import com.zndroid.utils.impl.NotchUtil;
import com.zndroid.utils.impl.PatternUtil;
import com.zndroid.utils.impl.ProcessUtil;
import com.zndroid.utils.impl.RawUtil;
import com.zndroid.utils.impl.RomUtil;
import com.zndroid.utils.impl.ScreenUtil;
import com.zndroid.utils.impl.StorageUtil;
import com.zndroid.utils.impl.StringUtil;
import com.zndroid.utils.impl.TimeUtil;

import java.lang.ref.WeakReference;

/**
 * @name:XUtils
 * @author:lazy
 * @email:luzhenyuxfcy@sina.com
 * @date : 2020/7/15 23:45
 * @version:
 * @description:工具集统一入口
 * */
@SuppressWarnings("unused")
public class XUtils {
    private static WeakReference<Context> context;
    private final ArrayMap<String, Object> utils = new ArrayMap<>();

    @SuppressWarnings("unchecked")
    private <T> T getUtil(@NonNull String name) {
        return (T) utils.get(name);
    }
    /**
     * 入口 start
     * */
    public AppUtil appUtil() {
        AppUtil impl = getUtil("AppUtil");
        if (null == impl) {
            impl = new AppUtil();
            utils.put("AppUtil", impl);
        }
        return impl;
    }
    public AssetsUtil assetsUtil() {
        AssetsUtil impl = getUtil("AssetsUtil");
        if (null == impl) {
            impl = new AssetsUtil();
            utils.put("AssetsUtil", impl);
        }
        return impl;
    }
    public CleanerUtil cleanerUtil() {
        CleanerUtil impl = getUtil("CleanerUtil");
        if (null == impl) {
            impl = new CleanerUtil();
            utils.put("CleanerUtil", impl);
        }
        return impl;
    }
    public CollectUtil collectUtil() {
        CollectUtil impl = getUtil("CollectUtil");
        if (null == impl) {
            impl = new CollectUtil();
            utils.put("CollectUtil", impl);
        }
        return impl;
    }
    public CryptoUtil cryptoUtil() {
        CryptoUtil impl = getUtil("CryptoUtil");
        if (null == impl) {
            impl = new CryptoUtil();
            utils.put("CryptoUtil", impl);
        }
        return impl;
    }
    public DeviceUtil deviceUtil() {
        DeviceUtil impl = getUtil("DeviceUtil");
        if (null == impl) {
            impl = new DeviceUtil();
            utils.put("DeviceUtil", impl);
        }
        return impl;
    }
    public FileUtil fileUtil() {
        FileUtil impl = getUtil("FileUtil");
        if (null == impl) {
            impl = new FileUtil();
            utils.put("FileUtil", impl);
        }
        return impl;
    }
    public NetUtil netUtil() {
        NetUtil impl = getUtil("NetUtil");
        if (null == impl) {
            impl = new NetUtil();
            utils.put("NetUtil", impl);
        }
        return impl;
    }
    public NotchUtil notchUtil() {
        NotchUtil impl = getUtil("NotchUtil");
        if (null == impl) {
            impl = new NotchUtil();
            utils.put("NotchUtil", impl);
        }
        return impl;
    }
    public PatternUtil patternUtil() {
        PatternUtil impl = getUtil("PatternUtil");
        if (null == impl) {
            impl = new PatternUtil();
            utils.put("PatternUtil", impl);
        }
        return impl;
    }
    public ProcessUtil processUtil() {
        ProcessUtil impl = getUtil("ProcessUtil");
        if (null == impl) {
            impl = new ProcessUtil();
            utils.put("ProcessUtil", impl);
        }
        return impl;
    }
    public RawUtil rawUtil() {
        RawUtil impl = getUtil("RawUtil");
        if (null == impl) {
            impl = new RawUtil();
            utils.put("RawUtil", impl);
        }
        return impl;
    }
    public ScreenUtil screenUtil() {
        ScreenUtil impl = getUtil("ScreenUtil");
        if (null == impl) {
            impl = new ScreenUtil();
            utils.put("ScreenUtil", impl);
        }
        return impl;
    }
    public StorageUtil storageUtil() {
        StorageUtil impl = getUtil("StorageUtil");
        if (null == impl) {
            impl = new StorageUtil();
            utils.put("StorageUtil", impl);
        }
        return impl;
    }
    public StringUtil stringUtil() {
        StringUtil impl = getUtil("StringUtil");
        if (null == impl) {
            impl = new StringUtil();
            utils.put("StringUtil", impl);
        }
        return impl;
    }
    public TimeUtil timeUtil() {
        TimeUtil impl = getUtil("TimeUtil");
        if (null == impl) {
            impl = new TimeUtil();
            utils.put("TimeUtil", impl);
        }
        return impl;
    }
    public ClipboardUtil clipboardUtil() {
        ClipboardUtil impl = getUtil("ClipboardUtil");
        if (null == impl) {
            impl = new ClipboardUtil();
            utils.put("ClipboardUtil", impl);
        }
        return impl;
    }
    public RomUtil romUtil() {
        RomUtil impl = getUtil("RomUtil");
        if (null == impl) {
            impl = new RomUtil();
            utils.put("RomUtil", impl);
        }
        return impl;
    }
    /**
     * 入口 end
     * */


    private XUtils(){}
    private static class $ {private static final XUtils $$ = new XUtils();}
    public static XUtils create() {
        return $.$$;
    }

    /**
     * 使用统一的Context,在初始化APP时传入，
     * 就可以通过{@link #getContext()}方法直接获取<code>ApplicationContext</code>，也可自定义传入
     * */
    public void uniformContext(Context context) {
        if (context instanceof Activity) {
            XUtils.context = new WeakReference<>(context.getApplicationContext());
        } else {
            XUtils.context = new WeakReference<>(context);
        }
    }

    public static Context getContext() {
        if (null == context) {
            throw new UnsupportedOperationException(">>> pls call #uniformContext(...) first,you can invoking at 'APP' Initializing strongly recommend.");
        }
        return XUtils.context.get();
    }
    /////////////////////////////////////
}
